////////////////////////////////////////////////////////////////////
// Programme de regroupement/partage du script de Chrono Cross
////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////
// Nemesis pour Terminus Traduction (tt_nemesis@yahoo.fr)
// Date de création :		08/09/03
// Dernière modification :	14/10/03
////////////////////////////////////////////////////////////////////

// Entete
#include "Partage.h"

// Type des blocs de script
typedef struct {
	int num;
	int nb1; // Début des blocs de débogage
	int nb2; // Reprise des blocs utiles
} Part_TBloc;

// Nombre de blocs des scénarii (cf Rooms.cpp)
Part_TBloc Part_Blocs[PART_FICHS_NB];
char  *Part_Nom;	// Nom du fichier texte en sortie
char  *Part_Titre;  // Titre du fichier assemblé
_int16 Part_Nb;
_int16 Part_Offset;
_int16 Part_Saut;
char  *Part_Scenar;

// Type des blocs de script
typedef struct {
	int nbl;
	char *nom;
} Part_TPerso;

// Noms des personnages trouvés et répartition
Part_TPerso Part_Persos[PART_PERSOS_MAX];
int Part_PersosNb=0;

/*------------------------------------------------------------------
  Initialisation des fichiers pour le regroupement/partage
------------------------------------------------------------------*/
void Part_Infos (void)
{
	// Fichier des infos
	FILE *infos_f;
	// Nom de l'iso (chemin)
	char infos_nom[PART_NOM_MAX];
	// Numero de fichier
	int num;
	// Numéros de blocs
	int nb1,nb2;
	// Ligne
	char ligne[PART_LIGNE_MAX];
	// Nombre de champs d'infos
	int result;
	// Infos des personnages
	int p,nbl;
	char *nom;

	// Ouverture du fichier des infos principales
	sprintf(infos_nom,"%s%s%s%s.%s",
		DIR_INFOS,DIR_INFOS_GRP,Part_Nom,PART_SUFFIXE,EXT_INFOS);
	infos_f=fopen(infos_nom,"rb");

	if (infos_f==NULL) {
		Main_Message_S("Erreur d'ouverture des infos.\n","",ER);
		return;
	} else {
		// Réinitialisation
		Part_Nb=0;
		// Titre des textes
		fgets(ligne,PART_LIGNE_MAX,infos_f);
		ligne[strlen(ligne)-2]=0;
		Part_Titre=strdup(ligne);
		// Numero de fichier d'offset
		fgets(ligne,PART_LIGNE_MAX,infos_f);
		sscanf(ligne,"%d",&Part_Offset);
		// Saut entre les fichiers
		fgets(ligne,PART_LIGNE_MAX,infos_f);
		sscanf(ligne,"%d",&Part_Saut);
		// Numero de fichier de texte
		fgets(ligne,PART_LIGNE_MAX,infos_f);
		ligne[strlen(ligne)-2]=0;
		Part_Scenar=strdup(ligne);
		// Récupération des noms de fichiers
		while (fgets(ligne,PART_LIGNE_MAX,infos_f)!=NULL)
			// Cas d'un commentaire ou d'un blanc
			if (ligne[0]!=COMMENT) {
				result=sscanf(ligne,"%04d %03d %03d",&num,&nb1,&nb2);
				switch (result) {
				case 3:
					Part_Blocs[Part_Nb].num=num;
					Part_Blocs[Part_Nb].nb1=nb1;
					Part_Blocs[Part_Nb].nb2=nb2;
					Part_Nb++;
					break;
				case 2:
					Part_Blocs[Part_Nb].num=num;
					Part_Blocs[Part_Nb].nb1=nb1;
					Part_Blocs[Part_Nb].nb2=0;
					Part_Nb++;
					break;
				default:
					Main_Message_S("Info erronee... ","",ER);
				}
			}
		// Fermeture du fichier des infos
		fclose(infos_f);
	}

	// Initialisation
	for(p=0;p<PART_PERSOS_MAX;p++)
		Part_Persos[p].nbl=0;

	// Ouverture du fichier des infos des personnages
	sprintf(infos_nom,"%s%s%s%s.%s",DIR_TXT_IN,Part_Nom,CD_SUFFIXE,PART_REPART,EXT_TXT);
	infos_f=fopen(infos_nom,"rb");

	if (infos_f==NULL)
		Main_Message_S("Aucun fichier de personnages present... ","",OK);
	else {
		// Saut du titre
		for(p=0;p<4;p++)
			fgets(ligne,PART_LIGNE_MAX,infos_f);
		// Récupération de la liste de personnages
		while (fgets(ligne,PART_LIGNE_MAX,infos_f)!=NULL)
			// Cas d'un commentaire ou d'un blanc
			if (ligne[0]!=COMMENT) {
				result=sscanf(ligne,PART_REPARTC_L,&nbl,&num);
				ligne[strlen(ligne)-2]=0;
				nom = &ligne[12];
				if (num!=Part_PersosNb) {
					Main_Message_S("Decalage dans les persos... ","",ER);
				}
				switch (result) {
				case 2:
					Part_Persos[Part_PersosNb].nom=strdup(nom);
					Part_PersosNb++;
					break;
				default:
					Main_Message_S("Info erronee... ","",ER);
				}
			}		
		// Fermeture du fichier des infos
		fclose(infos_f);
	}
}

/*------------------------------------------------------------------
  Ecriture d'une ligne de caractères
------------------------------------------------------------------*/
void Part_Ligne(int larg, FILE *out_f)
{
	int l;

	// Ecriture
	for(l=0;l<larg;l++)
		fputc(PART_SPEC_CAR,out_f);
}

/*------------------------------------------------------------------
  Affichage d'une ligne de caractères à l'écran
------------------------------------------------------------------*/
void Part_Message(char *message, int info, FILE *out_f)
{
	// Chaine, largeur et demi-largeur de caractères
	char chaine[PART_LIGNE_MAX];
	int demi,larg;

	// Création de la chaîne à écrire
	sprintf(chaine,message,info);
	larg=strlen(chaine)+2;
	demi=(PART_LARGEUR-larg)/2;
	// Ecriture
	Part_Ligne(PART_LARGEUR,out_f);
	fputc('\n',out_f);
	Part_Ligne(demi,out_f);
	fprintf(out_f," %s ",chaine);
	Part_Ligne(PART_LARGEUR-larg-demi,out_f);
	fputc('\n',out_f);
	Part_Ligne(PART_LARGEUR,out_f);
	fputc('\n',out_f);
}

/*------------------------------------------------------------------
  Regroupement du script en 1 seul fichier texte
  et génération du listing de répartition Blocs/Persos
--------------------------------------------------------------------
 <- i = numéro de texte de script
 <- b = numéro de bloc
 <- ligne = ligne à écrire
 <- out_f = fichier dans lequel écrire
------------------------------------------------------------------*/
void Part_Ecrit_Ligne (int i, int b, char *ligne, FILE *out_f)
{
	if (b<Part_Blocs[i].nb1 || b>=Part_Blocs[i].nb2)
		fputs(ligne, out_f);
}

/*------------------------------------------------------------------
  Regroupement du script en 1 seul fichier texte
  et génération du listing de répartition Blocs/Persos
--------------------------------------------------------------------
 <- infos = fichiers des informations des partages à faire
------------------------------------------------------------------*/
void Part_Regroupe (char *infos)
{
	// Fichiers entrants et sortants
	FILE *in_f,*out_f,*blocs_f,*repart_f;
	char dossier[PART_NOM_MAX];
	char fich_nom[PART_NOM_MAX];
	char *fich_nom2;
	// Noms des personnages trouvés et répartition
	char perso[PART_LIGNE_MAX];
	int p;
	// Indice et nombre de blocs
	int i,b,bloc_max;
	// Ligne
	char ligne[PART_LIGNE_MAX];
	int l;

	Main_Message_S("Rassemblement et listing : %s...",infos,OK);

	// Nom du fichier texte en sortie
	Part_Nom=strdup(infos);
	// Chargement des informations de partage
	Part_Infos();
	// Ouverture du fichier regroupé
	sprintf(fich_nom,"%s%s%s.%s",DIR_TXT_IN,Part_Nom,CD_SUFFIXE,EXT_TXT);
	out_f=fopen(fich_nom,"w");
	// Ouverture du listing des blocs
	sprintf(fich_nom,"%s%s%s%s.%s",DIR_TXT_IN,Part_Nom,CD_SUFFIXE,PART_BLOCS,EXT_TXT);
	blocs_f=fopen(fich_nom,"w");
	// Ecriture des titres
	Part_Message(Part_Titre,0,out_f);
	fputc('\n',out_f);
	Part_Message(Part_Titre,0,blocs_f);
	fputc('\n',blocs_f);
	// Copie effective
	for(i=0;i<Part_Nb;i++) {
		// Ouverture du fichier script
		sprintf(dossier,"%s%s%04d\\",DIR_FICH_IN,ENT_DOSSIER,
			Part_Saut*Part_Blocs[i].num+Part_Offset);
		Fichier_Cherche(dossier,Part_Scenar,EXT_TXT,&fich_nom2);
		sprintf(fich_nom,"%s%s",dossier,fich_nom2);
		in_f=fopen(fich_nom,"r");
		if (in_f==NULL)
			Main_Message_D("Script %03d introuvable.\n",Part_Blocs[i].num,ER);
		else {
			// Inscription du numéro de Room
			Part_Message("Room %03d",Part_Blocs[i].num,out_f);
			Part_Message("Room %03d",Part_Blocs[i].num,blocs_f);
			// Nombre de blocs
			fgets(ligne,PART_LIGNE_MAX,in_f);
			sscanf(ligne,"%d",&bloc_max);
			// Vérification de la limite des blocs
			if (Part_Blocs[i].nb2==0)
				Part_Blocs[i].nb2=bloc_max;
			// Recopie du script "utile" (hors débogage)
			fgets(ligne,PART_LIGNE_MAX,in_f);
			for(b=0;b<bloc_max;b++) {
				Part_Ecrit_Ligne(i,b,ligne,out_f);
				// Ligne initiale de largeur
				fgets(ligne,PART_LIGNE_MAX,in_f);
				Part_Ecrit_Ligne(i,b,ligne,out_f);
				// Début de gestion des persos
				// Copie de la ligne sans le 1er caractère
				fgets(ligne,PART_LIGNE_MAX,in_f);
				if (b<Part_Blocs[i].nb1 || b>=Part_Blocs[i].nb2) {
					strcpy(perso,&ligne[1]);
					if (perso[strlen(perso)-2]==':')
						perso[strlen(perso)-2]=NULL;
					else
						strcpy(perso, "Autres");
					// Recherche du personnage dans la liste
					for (p=0;p<Part_PersosNb && stricmp(perso, Part_Persos[p].nom);p++);
					if (p>=Part_PersosNb) {
						// Ajout d'un perso
						if (Part_PersosNb < PART_PERSOS_MAX) {
							Part_Persos[Part_PersosNb].nom=strdup(perso);
							(Part_Persos[Part_PersosNb].nbl)++;
							Part_PersosNb++;
						} else {
							Main_Message_S("Trop grand nombre de persos.\n","",ER);
							strcpy(perso, "Bug"); 
							printf(perso);
						}
					}
					// Ecriture du nom du personnage pour le bloc
					fprintf(blocs_f,"%05d : %03d\n",b,p);
				}
				// Fin de gestion des persos
				// Recopie des lignes restantes
				do {
					Part_Ecrit_Ligne(i,b,ligne,out_f);
					// Longueur de ligne pour test de fin de bloc
					l=strlen(ligne);
					// Mise à jour nombre de lignes
					(Part_Persos[p].nbl)++;
					fgets(ligne,PART_LIGNE_MAX,in_f);
				} while(ligne[0]==PART_DEB_A && feof(in_f)==0);
				// Test de fin de bloc (pour éviter de coller les
				// textes sans retours à la ligne intermédiaires)
				if ((b<Part_Blocs[i].nb1 || b>=Part_Blocs[i].nb2)
					&& l>2)
					fputs(PART_VIDE3,out_f);
			}
			// Fermeture du fichier
			fclose(in_f);
		}
	}
	// Ecriture des infos de répartition des personnages
	sprintf(fich_nom,"%s%s%s%s.%s",DIR_TXT_IN,Part_Nom,CD_SUFFIXE,PART_REPART,EXT_TXT);
	repart_f=fopen(fich_nom,"w");
	// Ecriture du titre
	Part_Message(Part_Titre,0,repart_f);
	fputc('\n',repart_f);
	// Inscription des infos
	for(p=0;p<Part_PersosNb;p++)
		fprintf(repart_f,PART_REPARTC_E,Part_Persos[p].nbl,p,Part_Persos[p].nom);
	// Fermeture des fichiers
	fclose(out_f);
	fclose(blocs_f);
	fclose(repart_f);

	Main_OK();
}

/*------------------------------------------------------------------
  Séparation du script en petits fichiers de rooms
--------------------------------------------------------------------
 <- infos = fichiers des informations des partages à faire
------------------------------------------------------------------*/
void Part_Partage (char *infos)
{
	// Fichier entrant, original et sortant
	FILE *in_f,*orig_f,*out_f;
	char dossier[PART_NOM_MAX];
	char fich_nom[PART_NOM_MAX];
	char *fich_nom2;
	// Indice et nombre de blocs
	int i,k,b,bloc_max;
	// Ligne
	char ligne[PART_LIGNE_MAX];

	Main_Message_S("Redistribution du script : %s...",infos,OK);

	// Nom du fichier texte en sortie
	Part_Nom=strdup(infos);
	// Chargement des informations de partage
	Part_Infos();
	// Ouverture du fichier regroupé
	sprintf(fich_nom,"%s%s%s.%s",DIR_TXT_OUT,Part_Nom,CD_SUFFIXE,EXT_TXT);
	in_f=fopen(fich_nom,"r");
	// Test d'ouverture
	if (in_f==NULL)
		Main_Message_S("Script regroupe introuvable.\n","",ER);
	else {
		// Saut de l'entête + 1ère ligne de room
		for(k=0;k<5;k++)
			fgets(ligne,PART_LIGNE_MAX,in_f);	
		// Copie effective
		// Parcours des rooms
		for(i=0;i<Part_Nb;i++) {
			// Ouverture du fichier script original
			sprintf(dossier,"%s%s%04d\\",DIR_FICH_IN,ENT_DOSSIER,
				Part_Saut*Part_Blocs[i].num+Part_Offset);
			Fichier_Cherche(dossier,Part_Scenar,EXT_TXT,&fich_nom2);
			sprintf(fich_nom,"%s%s",dossier,fich_nom2);
			orig_f=fopen(fich_nom,"r");
			// Tests d'ouverture
			if (orig_f==NULL)
				Main_Message_D("Script %03d introuvable.\n",i,ER);
			else {
				// Ouverture du fichier script traduit
				sprintf(dossier,"%s%s%04d\\",DIR_FICH_OUT,ENT_DOSSIER,
					Part_Saut*Part_Blocs[i].num+Part_Offset);
				sprintf(fich_nom,"%s%s",dossier,fich_nom2);
				out_f=fopen(fich_nom,"w");
				// Saut du numéro de Room (1 déjà lue)
				for(k=0;k<2;k++)
					fgets(ligne,PART_LIGNE_MAX,in_f);
				// Nombre de blocs
				fgets(ligne,PART_LIGNE_MAX,orig_f);
				sscanf(ligne,"%d",&bloc_max);
				// Vérification de la limite des blocs
				if (Part_Blocs[i].nb2==0)
					Part_Blocs[i].nb2=bloc_max;
				fprintf(out_f,"%05d\n",bloc_max);
				// Recopie du script
				fgets(ligne,PART_LIGNE_MAX,in_f);
				for(b=0;b<bloc_max;b++) {
					// Bloc utile
					if (b<Part_Blocs[i].nb1 || b>=Part_Blocs[i].nb2) {
						// Première ligne
						fputs(ligne,out_f);
						// Recopie des lignes restantes
						fgets(ligne,PART_LIGNE_MAX,in_f);
						do {
							fputs(ligne,out_f);
							fgets(ligne,PART_LIGNE_MAX,in_f);
						} while((ligne[0]==PART_DEB_A
							|| ligne[0]==PART_DEB_1) && !feof(in_f));
					}
					// Bloc vide
					else {
						fprintf(out_f,PART_VIDE1,b);
						fprintf(out_f,PART_VIDE2);
						fprintf(out_f,PART_VIDE3);
					}
				}
				// Fermeture des fichiers
				fclose(out_f);
				fclose(orig_f);
			}
		}
		// Fermeture du fichier d'entrée
		fclose(in_f);
		Main_OK();
	}
}